package org.phalanx.servlet.websession;

import java.util.Enumeration;
import java.util.Hashtable;

import javax.servlet.http.Cookie;

import org.phalanx.server.PhalanxServer;
import org.phalanx.server.ServerCache.CacheManager;
import org.phalanx.server.ServerCache.Cacheable;
import org.phalanx.server.user.PhalanxUser;
import org.phalanx.server.user.UserManager;

public class ServletAuthenticatorManager {
	private PhalanxServer pServer;
	private UserManager u;
	
	public ServletAuthenticatorManager(PhalanxServer serverInstance){
		this.pServer = serverInstance;
		u = new UserManager(pServer.getCacheManager());
	}
	
	private boolean isAuthenticated(String username, String password){
		boolean isSuccess = false;
		
		PhalanxUser authUser = u.getUserByName(username);
		
		if (authUser != null){
			isSuccess = isPasswordMatch(password, authUser.getPassword());
		}
		
		return isSuccess;
	}
	
	private boolean isCookieValid(String cookieId){
		boolean isSuccess = false;

		if (cookieId != null){
			CacheManager c = pServer.getCacheManager();

			Cacheable session = c.getCache("TokenSessionCache").get(cookieId);
			
			if (session != null){
				isSuccess = true;
			}
		}
		return isSuccess;
	}
	
	public Cookie authenticate(Cookie id){
		Cookie cookieId = null;
		
		if(this.isCookieValid(id.getValue())){
			cookieId = id;
		}
		
		return cookieId;
	}
	
	public Cookie authenticate(String username, String password){
		Cookie cookieId = null;
		CacheManager cacheMgr = pServer.getCacheManager();
		
		if (this.isAuthenticated(username, password)){
			PhalanxUser authUser = u.getUserByName(username);
			SessionCookieFactory cookieMaker = new SessionCookieFactory();
			
			if (getCookieByUserId(authUser.getId()) != null){
				// If cookie already exists in the system user it
				cookieId = getCookieByUserId(authUser.getId());
			}
			else {
				cookieId = cookieMaker.generateCookie("phalanxsessionid", 40);
				// TODO Generate CookieId and do some post authentication cache stuff.
				cacheMgr.setElement("ActiveSessionCache", authUser.getId(), authUser);

				// TODO create and setup session
				cacheMgr.setElement("TokenSessionCache", cookieId.getValue(), authUser);
			}
			
		}
		
		return cookieId;
	}
	
	private Cookie getCookieByUserId(Integer userId){
		Cookie sessionCookie = null;
		CacheManager cacheMgr = pServer.getCacheManager();
		
		Hashtable<Object,Cacheable> ct = cacheMgr.getCache("TokenSessionCache").getInternalCacheTable();
		Enumeration<Object> e = ct.keys();
	
		while(e.hasMoreElements()){
			String cookieId = (String)e.nextElement();
			PhalanxUser temp = (PhalanxUser)ct.get(cookieId);
			
			if (temp.getId().equals(userId)){
				sessionCookie = new SessionCookieFactory().generateCookie("phalanxsessionid", 40);
				sessionCookie.setValue(cookieId);
				break;
			}
		}
		
		return sessionCookie;
	}
	
	public boolean logoutUser(String tokenId){
		boolean isSuccess = false;
		
		if (isCookieValid(tokenId)){
			isSuccess = true;
			
			CacheManager cacheMgr = pServer.getCacheManager();
			PhalanxUser logoutUser = (PhalanxUser)cacheMgr.getElement("TokenSessionCache", tokenId);
			cacheMgr.removeElement("ActiveSessionCache", logoutUser.getId());
			cacheMgr.removeElement("TokenSessionCache", tokenId);
			UserWebSession session = (UserWebSession)cacheMgr.getElement("UserWebFeedCache", logoutUser.getId());
			
			if (session != null){
				cacheMgr.removeElement("UserWebFeedCache", logoutUser.getId());
			}
		}
		
		return isSuccess;
	}
	
	private boolean isPasswordMatch(String password, String challenge){
		boolean isMatch = false;
		
		if (password != null && challenge != null && password.equalsIgnoreCase(challenge)){
			isMatch = true;
		}
		else if (password == null && challenge == null){
			isMatch = true;
		}
		
		return isMatch;
	}
}
